package com.chlitina.store.modules.cash.service;

import java.util.ArrayList;
import java.util.List;

import com.chlitina.store.common.utils.DataFormater;
import com.chlitina.store.modules.base.entity.StoreCardTemplateDuration;
import com.chlitina.store.modules.base.entity.StoreCardTemplateProductDetail;
import com.chlitina.store.modules.base.entity.StoreCardTemplateTimes;
import com.chlitina.store.modules.base.entity.StoreCare;
import com.chlitina.store.modules.cash.entity.StoreCardDuration;
import com.chlitina.store.modules.cash.entity.StoreCardTimes;
import com.chlitina.store.modules.cash.model.AllCardPayment;
import com.chlitina.store.modules.cash.model.AllCardPaymentDetail;
import com.chlitina.store.modules.cash.model.CardPayment;
import com.chlitina.store.modules.cash.model.DurationCardPayment;
import com.chlitina.store.modules.cash.model.ProductCardPayment;
import com.chlitina.store.modules.cash.model.TimesCardPayment;
import com.chlitina.store.modules.cash.model.recharge.CardAllRecharge;
import com.chlitina.store.modules.cash.model.recharge.Recharge;
import com.chlitina.store.modules.employee.entity.Employee;

public class PaymentUility {
	public static ProductCardPayment findCardProductPaymentByPaymentId(
			List<ProductCardPayment> cards, long paymentID) {
		for (ProductCardPayment cardPayment : cards) {
			if (cardPayment.getPaymentId() == paymentID) {
				return cardPayment;
			}
		}
		return null;

	}

	public static Employee findEmployeeById(List<Employee> employees, long id) {
		for (Employee e : employees) {
			if (e.getId().longValue() == id) {
				return e;
			}
		}
		return null;
	}

	public static AllCardPayment findCardAllPaymentByPaymentId(
			List<AllCardPayment> allCardPayments, long id) {
		for (AllCardPayment cardPayment : allCardPayments) {
			if (cardPayment.getPaymentId() == id) {
				return cardPayment;
			}
		}
		return null;
	}

	public static List<AllCardPayment> findAllCardsForNewcard(
			List<AllCardPayment> cards, float realMoney) {
		List<AllCardPayment> result = new ArrayList<AllCardPayment>();
		for (AllCardPayment payment : cards) {
			if(payment.isNewCard()){
				continue;
			}
			payment.setRealCost(realMoney);
			if (payment.getCurrentMoney() >= realMoney) {
				result.add(payment);
			}
		}
		return result;
	}

	public static AllCardPayment findBestAllCardPaymentForNewcard(
			List<AllCardPayment> cards, float money) {
		return bestAllCardsForNewcard(findAllCardsForNewcard(cards, money));
	}

	/**
	 * Find the less money card to pay
	 * @param cards
	 * @return
	 */
	public static AllCardPayment bestAllCardsForNewcard(
			List<AllCardPayment> cards) {
		AllCardPayment target = null;
		for (AllCardPayment payment : cards) {
			if (target == null) {
				target = payment;
			} else {
				if (payment.getCurrentMoney()< target.getCurrentMoney()) {
					target = payment;
				}
			}
		}
		return target;
	}

	public static List<AllCardPayment> findAllCardsForProduct(
			List<AllCardPayment> cards, float appendTopay) {
		List<AllCardPayment> result = new ArrayList<AllCardPayment>();
		float realMoney = 0;
		for (AllCardPayment payment : cards) {
			realMoney = appendTopay * payment.getCard().getProductDiscount();
			realMoney=DataFormater.formatMoneyFloat(realMoney);
			payment.setRealCost(realMoney);
			if (payment.getMoney() + realMoney <= payment.getCard().getMoney()) {
				result.add(payment);
			}
		}
		return result;
	}

	public static List<ProductCardPayment> findProductCardsForProduct(
			List<ProductCardPayment> cards, long pid, float momey) {
		List<ProductCardPayment> result = new ArrayList<ProductCardPayment>();
		List<StoreCardTemplateProductDetail> productList = null;
		float realMoney = 0;
		for (ProductCardPayment card : cards) {
			productList = card.getCard().getTemplate().getProductList();
			realMoney = card.getCard().getProductDiscount() * momey;
			realMoney=DataFormater.formatMoneyFloat(realMoney);
			SECOND: for (StoreCardTemplateProductDetail detail : productList) {
				if (detail.getStoreProduct().getId().longValue() == pid) {
					if (card.getCard().getMoney() - realMoney - card.getMoney() >= 0) {
						card.setRealCost(realMoney);
						result.add(card);
					}
					break SECOND;
				}
			}
		}
		return result;
	}

	public static List<DurationCardPayment> findDurationCards(
			List<DurationCardPayment> cards, long careid) {
		List<DurationCardPayment> result = new ArrayList<DurationCardPayment>();
		for (DurationCardPayment card : cards) {
			StoreCardDuration durationCard = card.getCard();
			StoreCardTemplateDuration template = durationCard.getTemplate();
			StoreCare storeCare = template.getStoreCare();
			if (storeCare.getId().longValue() == careid) {
				result.add(card);
			}
		}
		return result;
	}

	public static List<TimesCardPayment> findTimesCards(
			List<TimesCardPayment> cards, long careid) {
		List<TimesCardPayment> result = new ArrayList<TimesCardPayment>();
		for (TimesCardPayment card : cards) {
			StoreCardTimes timesCard = card.getCard();
			StoreCardTemplateTimes template = timesCard.getTemplate();
			StoreCare storeCare = template.getStoreCare();
			if (storeCare.getId().longValue() == careid) {
				result.add(card);
			}
		}
		return result;
	}

	public static void main(String[] args) {
		System.out.println(Float.MAX_VALUE);
	}

	public static CardPayment findBestDurationCard(
			List<DurationCardPayment> avaibleDurationCards, long longValue,
			float totalRequired) {
		List<DurationCardPayment> cards = findDurationCards(
				avaibleDurationCards, longValue);
		if (cards.isEmpty()) {
			return null;
		}
		return cards.get(0);
	}

	private static TimesCardPayment bestTimesCardPayment(
			List<TimesCardPayment> cards) {
		TimesCardPayment target = null;
		float costPertime = Float.MAX_VALUE;
		for (TimesCardPayment card : cards) {
			if (card.getCard().getCostPerTime() < costPertime) {
				costPertime = card.getCard().getCostPerTime();
				target = card;
			}
		}
		return target;
	}

	public static CardPayment findBestTimesCard(List<TimesCardPayment> cards,
			long careid) {
		return bestTimesCardPayment(findTimesCards(cards, careid));
	}

	/**
	 * find the best discount, that is less money need to pay
	 * @param cards
	 * @return
	 */
	private static ProductCardPayment bestProductCardPayment(
			List<ProductCardPayment> cards) {
		ProductCardPayment target = null;
		float realCost = Float.MAX_VALUE;
		for (ProductCardPayment card : cards) {
			if (card.getRealCost() < realCost) {
				realCost = card.getRealCost();
				target = card;
			}
		}
		return target;
	}

	private static AllCardPayment bestAllCardPayment(List<AllCardPayment> cards) {
		AllCardPayment target = null;
		float realCost = Float.MAX_VALUE;
		for (AllCardPayment card : cards) {
			if (card.getRealCost() < realCost) {
				realCost = card.getRealCost();
				target = card;
			}
		}
		return target;
	}

	public static AllCardPayment findBestAllCardForProduct(
			List<AllCardPayment> avaibleAllCards, float totalRequired) {
		return bestAllCardPayment(findAllCardsForProduct(avaibleAllCards,
				totalRequired));
	}

	public static AllCardPayment findBestAllCardForCare(
			List<AllCardPayment> avaibleAllCards, float requiredTotal) {
		return bestAllCardPayment(findAllCardsForCare(avaibleAllCards,
				requiredTotal));
	}

	private static List<AllCardPayment> findAllCardsForCare(
			List<AllCardPayment> cards, float requiredTotal) {
		List<AllCardPayment> result = new ArrayList<AllCardPayment>();
		float realMoney = 0;
		for (AllCardPayment payment : cards) {
			realMoney = requiredTotal * payment.getCard().getCareDiscount();
			realMoney=DataFormater.formatMoneyFloat(realMoney);
			payment.setRealCost(realMoney);
			if (payment.getMoney() + realMoney <= payment.getCard().getMoney()) {
				result.add(payment);
			}
		}
		return result;
	}

	public static ProductCardPayment findBestProductCard(
			List<ProductCardPayment> cards, long pid, float totalRequired) {
		return bestProductCardPayment(findProductCardsForProduct(cards, pid,
				totalRequired));
	}

	public static ProductCardPayment findCardProductPaymentByProduct(
			List<ProductCardPayment> cards, long cardId) {
		for (ProductCardPayment card : cards) {
			if (card.getCard().getId().longValue() == cardId) {
				return card;
			}
		}
		return null;
	}

	public static AllCardPaymentDetail findCardAllPaymentDetailByPaymentId(
			List<AllCardPaymentDetail> cardsPaymentDetails, long cardid) {
		for (AllCardPaymentDetail detail : cardsPaymentDetails) {
			if (detail.getCardPayment().getPaymentId() == cardid) {
				return detail;
			}
		}
		return null;
	}

	public static AllCardPayment findBestAllCardPayment(
			List<AllCardPayment> avaibleAllCards, Recharge recharge) {
		if(avaibleAllCards.isEmpty() || recharge instanceof CardAllRecharge){
			 return null;
		 }
		return bestAllCardPayment(findAllCards(avaibleAllCards,recharge.getMoney()));
	}

	private static List<AllCardPayment> findAllCards(List<AllCardPayment> cards,
			float requiredTotal) {
		List<AllCardPayment> result = new ArrayList<AllCardPayment>();
		float realMoney =requiredTotal;
		for (AllCardPayment payment : cards) {
			payment.setRealCost(realMoney);
			if (payment.getMoney() + realMoney <= payment.getCard().getMoney()) {
				result.add(payment);
			}
		}
		return result;
		
	}

}
